﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace HynuIOTA.IService
{
    public interface IServiceBase<T> where T : class, new()
    {
        #region 1.0 新增方法
        /// <summary>
        /// 新增方法
        /// </summary>
        /// <param name="model">模型</param>
        /// <returns></returns>
        void Add(T model);
        #endregion

        #region 2.0 删除方法
        /// <summary>
        /// 删除方法
        /// </summary>
        /// <param name="model">模型</param>
        /// <returns></returns>
        void Delete(T model);

        /// <summary>
        /// 根据条件删除
        /// </summary>
        /// <param name="where">删除的条件</param>
        /// <returns></returns>
        void DeleteBy(Expression<Func<T, bool>> whereLambda);
        #endregion

        #region 3.0 修改方法
        /// <summary>
        /// 修改实体
        /// </summary>
        /// <param name="model">模型</param>
        /// <returns></returns>
        void Modify(T model);

        /// <summary>
        /// 修改实体
        /// </summary>
        /// <param name="model">模型</param>
        /// <param name="modifiedPropertyNames">修改的属性</param>
        /// <returns></returns>
        void Modify(T model, params string[] modifiedPropertyNames);

        /// <summary>
        /// 通过从给定对象中读取值来设置此字典的值。给定对象可以是任何类型。如果对象具有任何与字典中的属性名称匹配且可读取的名称的属性，则将读取这些属性。其他属性将被忽略。例如，这样便能从简单的数据传输对象(DTO) 中复制属性。
        /// </summary>
        /// <param name="model"></param>
        /// <param name="obj"></param>
        void ModifyValue(T model, object obj);

        /// <summary>
        /// 修改指定实体
        /// </summary>
        /// <param name="whereLamdba">修改条件</param>
        /// <param name="modifyPropertyNamesValues">修改属性键值对</param>
        /// <returns></returns>
        void ModifyBy(Expression<Func<T, bool>> whereLamdba, Dictionary<string, object> modifyPropertyNamesValues);
        #endregion

        #region 4.0 查询方法
        /// <summary>
        /// 查询返回的第一个或默认
        /// </summary>
        /// <param name="whereLamdba">查询条件</param>
        /// <returns></returns>
        T WhereFristOrDefault(Expression<Func<T, bool>> whereLamdba);

        /// <summary>
        /// 根据指定条件查询 - 延时
        /// </summary>
        /// <param name="whereLamdba">查询条件</param>
        /// <returns></returns>
        IQueryable<T> Where(Expression<Func<T, bool>> whereLamdba);

        /// <summary>
        /// 根据指定条件进行连接查询 - 延时
        /// </summary>
        /// <param name="whereLamdba">查询条件</param>
        /// <param name="foreignKeyPropertyNames">外键属性名</param>
        /// <returns></returns>
        IQueryable<T> Where(Expression<Func<T, bool>> whereLamdba, params string[] foreignKeyPropertyNames);

        /// <summary>
        /// 根据指定条件查询并排序 - 延时
        /// </summary>
        /// <typeparam name="TKey">排序字段类型</typeparam>
        /// <param name="whereLamdba">查询条件</param>
        /// <param name="orderBy">排序字段</param>
        /// <param name="isAsc">是否升序</param>
        /// <returns></returns>
        IQueryable<T> WhereOrderBy<TKey>(Expression<Func<T, bool>> whereLamdba, Expression<Func<T,TKey>> orderBy, bool isAsc = true);

        /// <summary>
        /// /根据指定条件进行连接查询、排序 - 延时
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="whereLamdba">查询条件</param>
        /// <param name="orderBy">排序字段</param>
        /// <param name="isAsc">是否升序</param>
        /// <param name="foreignKeyPropertyNames">连接查询外键名称</param>
        /// <returns></returns>
        IQueryable<T> WhereOrderBy<TKey>(Expression<Func<T, bool>> whereLamdba, Expression<Func<T, TKey>> orderBy, bool isAsc = true,params string[] foreignKeyPropertyNames);

        /// <summary>
        /// 根据指定条件进行分页查询、排序 - 延时
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="pageData"></param>
        /// <param name="whereLamdba"></param>
        /// <param name="orderBy"></param>
        /// <param name="isAsc"></param>
        /// <returns></returns>
        IQueryable<T> WherePage<TKey>(Entity.FormatEntity.PageData pageData, Expression<Func<T, bool>> whereLamdba,
            Expression<Func<T, TKey>> orderBy, bool isAsc = true);

        /// <summary>
        /// 根据指定条件进行连接分页查询、排序 - 延时
        /// </summary>
        /// <typeparam name="TKey">排序字段类型</typeparam>
        /// <param name="pageData">页面数据</param>
        /// <param name="whereLamdba">查询条件</param>
        /// <param name="orderBy">排序字段</param>
        /// <param name="isAsc">是否升序</param>
        /// <param name="foreignKeyPropertyNames">连接查询外键名称</param>
        /// <returns></returns>
        IQueryable<T> WherePage<TKey>(Entity.FormatEntity.PageData pageData, Expression<Func<T, bool>> whereLamdba,
            Expression<Func<T, TKey>> orderBy, bool isAsc = true, params string[] foreignKeyPropertyNames);

        /// <summary>
        /// 根据指定条件进行分页查询、排序 - 异步
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="pageData"></param>
        /// <param name="whereLamdba"></param>
        /// <param name="orderBy"></param>
        /// <param name="isAsc"></param>
        /// <returns></returns>
        Task<IQueryable<T>> WherePageAsync<TKey>(Entity.FormatEntity.PageData pageData, Expression<Func<T, bool>> whereLamdba,
            Expression<Func<T, TKey>> orderBy, bool isAsc = true);

        /// <summary>
        /// 根据指定条件进行连接分页查询、排序 - 异步
        /// </summary>
        /// <typeparam name="TKey">排序字段类型</typeparam>
        /// <param name="pageData">页面数据</param>
        /// <param name="whereLamdba">查询条件</param>
        /// <param name="orderBy">排序字段</param>
        /// <param name="isAsc">是否升序</param>
        /// <param name="foreignKeyPropertyNames">连接查询外键名称</param>
        /// <returns></returns>
        Task<IQueryable<T>> WherePageAsync<TKey>(Entity.FormatEntity.PageData pageData, Expression<Func<T, bool>> whereLamdba,
            Expression<Func<T, TKey>> orderBy, bool isAsc = true, params string[] foreignKeyPropertyNames);
        #endregion
    }
}
